<template>
	<div class="person-selector">
		<el-select
			v-model="selectedValue"
			:placeholder="placeholder"
			:multiple="multiple"
			:clearable="clearable"
			:disabled="disabled"
			:filterable="true"
			:remote="true"
			:remote-method="handleRemoteSearch"
			:loading="loading"
			:size="size"
			:collapse-tags="collapseTags"
			:collapse-tags-tooltip="collapseTagsTooltip"
			class="width100"
			@change="handleChange"
			@clear="handleClear"
			@focus="handleFocus"
			@blur="handleBlur"
		>
			<el-option
				v-for="(person, idx) in filteredPersonOptions"
				:key="getOptionKey(person, idx)"
				:label="getDisplayLabel(person)"
				:value="getValue(person)"
			>
				<div class="person-option">
					<div class="person-main">
						<span class="person-name">{{ person?.Name || '' }}</span>
						<span class="person-staff-no">{{ person?.StaffNo || '' }}</span>
					</div>
					<div class="person-extra" v-if="showExtraFields">
						<span v-if="person?.Groupname" class="person-dept">{{ person?.Groupname }}</span>
						<span v-if="person?.JobPositionName" class="person-position">{{ person?.JobPositionName }}</span>
					</div>
				</div>
			</el-option>
		</el-select>
	</div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue';
import { ElSelect, ElOption } from 'element-plus';
import { SysPersonApi } from '/@/views/person/sysperson/api';
import type { ISysPersonView } from '/@/views/person/sysperson/api/interface';

// 组件属性定义
interface PersonSelectorProps {
	// 基础属性
	modelValue?: string | string[] | number | number[] | null;
	placeholder?: string;
	multiple?: boolean;
	clearable?: boolean;
	disabled?: boolean;
	size?: 'large' | 'default' | 'small';

	// 显示配置
	displayFields?: string[]; // 要显示的字段，如 ['Name', 'StaffNo', 'Group.Name']
	valueField?: string; // 值字段，默认为 'ID'
	labelFormat?: string; // 标签格式，如 '{Name}({StaffNo})'
	showExtraFields?: boolean; // 是否显示额外字段（部门、职位等）

	// 多选配置
	collapseTags?: boolean;
	collapseTagsTooltip?: boolean;

	// 搜索配置
	searchFields?: string[]; // 搜索字段，如 ['Name', 'StaffNo']
	minSearchLength?: number; // 最小搜索长度
	searchDelay?: number; // 搜索延迟（毫秒）
	pageSize?: number; // 每页数量

	// 过滤配置
	filters?: Record<string, any>; // 额外的过滤条件
	onlyActive?: boolean; // 只显示在职人员
	groupId?: string | null; // 部门ID，用于限制只能选择特定部门的人员
	excludePersonIds?: string | string[] | null; // 要排除的人员ID（单个或数组）

	// 预填充（编辑场景回显用）
	prefillPerson?: any | null; // 例如 { ID, Name, StaffNo }
}

const props = withDefaults(defineProps<PersonSelectorProps>(), {
	placeholder: '请输入工号或者姓名查询人员',
	multiple: false,
	clearable: true,
	disabled: false,
	size: 'default',
	displayFields: () => ['Name', 'StaffNo'],
	valueField: 'ID',
	labelFormat: '{Name}({StaffNo})',
	showExtraFields: true,
	collapseTags: true,
	collapseTagsTooltip: true,
	searchFields: () => ['Name', 'StaffNo'],
	minSearchLength: 1,
	searchDelay: 300,
	pageSize: 20,
	filters: () => ({}),
	onlyActive: true,
	groupId: null,
	excludePersonIds: null,
	prefillPerson: null,
});

// 事件定义
const emit = defineEmits<{
	'update:modelValue': [value: string | string[] | number | number[] | null];
	change: [value: string | string[] | number | number[] | null, person: ISysPersonView | ISysPersonView[] | null];
	clear: [];
	focus: [event: FocusEvent];
	blur: [event: FocusEvent];
	search: [query: string];
}>();

// 响应式数据
const loading = ref(false);
const personOptions = ref<ISysPersonView[]>([]);
const searchTimer = ref<NodeJS.Timeout | null>(null);
const api = SysPersonApi();

// 计算属性
const selectedValue = computed({
	get: () => {
		// 确保返回的值符合Element Plus el-select的要求
		const value = props.modelValue;
		if (value === null || value === undefined || value === '') {
			return props.multiple ? [] : '';
		}
		return value;
	},
	set: (value) => {
		// 确保发送给父组件的值符合预期
		if (props.multiple) {
			emit('update:modelValue', Array.isArray(value) && value.length > 0 ? value : null);
		} else {
			emit('update:modelValue', value && value !== '' ? value : null);
		}
	},
});

// 过滤有效的人员选项
const filteredPersonOptions = computed(() => {
	// 构建排除ID列表
	const excludeIds: string[] = [];
	if (props.excludePersonIds) {
		if (Array.isArray(props.excludePersonIds)) {
			excludeIds.push(...props.excludePersonIds.filter((id) => id !== null && id !== undefined));
		} else {
			excludeIds.push(props.excludePersonIds);
		}
	}

	return personOptions.value.filter((person) => {
		// 基本验证
		if (!person || !person.ID || person.ID === null || person.ID === undefined) {
			return false;
		}
		// 排除指定的人员ID
		if (excludeIds.length > 0 && excludeIds.includes(person.ID)) {
			return false;
		}
		return true;
	});
});

// 获取显示标签
const getDisplayLabel = (person: any): string => {
	if (!person || !person.ID || person.ID === null || person.ID === undefined) return '';

	let label = props.labelFormat;
	return label
		.replace('{Name}', person.Name ?? '')
		.replace('{StaffNo}', person.StaffNo ?? '')
		.replace('{Group.Name}', person.Groupname ?? '')
		.replace('{JobPosition.Name}', person.JobPositionName ?? '');
};

// 获取值
const getValue = (person: any): any => {
	if (!person || !person.ID || person.ID === null || person.ID === undefined) return null;

	if (props.valueField === 'ID') {
		// 优先使用ID，如果没有则使用StaffNo作为备选
		return person.ID ?? person.StaffNo ?? null;
	}
	const keys = props.valueField.split('.');
	let value: any = person;
	for (const key of keys) {
		value = value?.[key];
		if (value === undefined || value === null) break;
	}
	return value ?? null;
};

// 获取选项唯一键，避免无ID时不渲染
const getOptionKey = (person: any, idx: number) => {
	if (!person || !person.ID || person.ID === null || person.ID === undefined) return `empty-${idx}`;
	return person.ID ?? person.StaffNo ?? `${person.Name ?? 'row'}-${idx}`;
};

// 远程搜索处理
const handleRemoteSearch = (query: string) => {
	emit('search', query);

	if (!query || query === '' || query.trim().length < props.minSearchLength) {
		personOptions.value = [];
		return;
	}

	// 清除之前的定时器
	if (searchTimer.value) {
		clearTimeout(searchTimer.value);
	}

	// 设置新的定时器
	searchTimer.value = setTimeout(() => {
		searchPersons(query.trim());
	}, props.searchDelay);
};

// 搜索人员
const searchPersons = async (query: string) => {
	try {
		loading.value = true;

		// 构建搜索条件
		const searchData: any = {
			PageIndex: 1,
			...props.filters,
		};

		// 只显示在职人员
		if (props.onlyActive) {
			searchData.States = ['在职', '试用期', '待入职'];
		}

		// 如果指定了部门ID，则只搜索该部门的人员
		if (props.groupId) {
			searchData.GroupId = props.groupId;
		}

		// 智能区分：中文 -> 按姓名；纯数字 -> 按工号；其它 -> 默认按姓名
		const isChinese = /[\u4e00-\u9fa5]/.test(query);
		const isDigits = /^\d+$/.test(query);

		if (isDigits) {
			// 纯数字：只按工号搜索
			if (props.searchFields.includes('StaffNo')) {
				searchData.StaffNo = query;
			}
		} else {
			// 中文或其它：按姓名搜索
			if (props.searchFields.includes('Name')) {
				searchData.Name = query;
			}
		}

		const response = await api.search(searchData);

		// 使用接口返回的实际数据格式
		let dataList: any[] = [];

		if (response.Data && Array.isArray(response.Data)) {
			// 使用 response.Data
			dataList = response.Data;
		} else if (response.data && Array.isArray(response.data)) {
			// 使用 response.data
			dataList = response.data;
		} else {
			dataList = [];
		}

		personOptions.value = dataList.filter((person) => person && person.ID && person.ID !== null && person.ID !== undefined);
	} catch (error) {
		console.error('搜索人员失败:', error);
		personOptions.value = [];
	} finally {
		loading.value = false;
	}
};

// 值变化处理
const handleChange = (value: any) => {
	let selectedPersons: ISysPersonView | ISysPersonView[] | null = null;

	if (props.multiple) {
		if (Array.isArray(value) && value.length > 0) {
			selectedPersons = filteredPersonOptions.value.filter((person) => value.includes(getValue(person)));
		} else {
			selectedPersons = [];
		}
	} else {
		if (value !== null && value !== undefined && value !== '') {
			selectedPersons = filteredPersonOptions.value.find((person) => getValue(person) === value) || null;
		} else {
			selectedPersons = null;
		}
	}

	emit('change', value, selectedPersons);
};

// 清空处理
const handleClear = () => {
	// 不要清空 personOptions，只触发清空事件
	emit('clear');
};

// 聚焦处理
const handleFocus = (event: FocusEvent) => {
	emit('focus', event);
};

// 失焦处理
const handleBlur = (event: FocusEvent) => {
	emit('blur', event);
};

// 根据已选值加载对应的人员信息
const loadSelectedPersons = async () => {
	if (!props.modelValue || props.modelValue === '' || (Array.isArray(props.modelValue) && props.modelValue.length === 0)) {
		personOptions.value = [];
		return;
	}

	try {
		const values = Array.isArray(props.modelValue) ? props.modelValue : [props.modelValue];
		const loadPromises = values.map(async (value) => {
			if (!value || value === '') return null;
			try {
				const response = await api.get(value);
				return response.data?.Entity || null;
			} catch {
				return null;
			}
		});

		const persons = await Promise.all(loadPromises);
		personOptions.value = persons.filter((person) => person && person.ID && person.ID !== null && person.ID !== undefined) as ISysPersonView[];
	} catch (error) {
		console.error('加载已选人员失败:', error);
		personOptions.value = [];
	}
};

// 监听modelValue变化
watch(
	() => props.modelValue,
	(newVal) => {
		if (newVal && newVal !== '' && (Array.isArray(newVal) ? newVal.length > 0 : true)) {
			loadSelectedPersons();
		} else {
			personOptions.value = [];
		}
	},
	{ immediate: true }
);

// 监听预填充数据（用于编辑场景回显）
watch(
	() => props.prefillPerson,
	(newVal) => {
		if (!newVal || !newVal.ID || newVal.ID === null || newVal.ID === undefined) return;
		// 若当前选项列表中不存在该人员，则插入
		const targetVal = getValue(newVal);
		if (targetVal) {
			const exists = filteredPersonOptions.value.some((p) => getValue(p) === targetVal);
			if (!exists) {
				personOptions.value = [newVal, ...personOptions.value];
			}
		}
	},
	{ immediate: true }
);

// 组件挂载时的初始化
onMounted(() => {
	if (props.modelValue && props.modelValue !== '' && (Array.isArray(props.modelValue) ? props.modelValue.length > 0 : true)) {
		loadSelectedPersons();
	}
});
</script>

<style scoped lang="scss">
.person-selector {
	width: 100%;

	.person-option {
		.person-main {
			display: flex;
			align-items: center;
			gap: 8px;

			.person-name {
				font-weight: 500;
				color: var(--el-text-color-primary);
			}

			.person-staff-no {
				color: var(--el-text-color-regular);
				font-size: 12px;
				background: var(--el-fill-color-light);
				padding: 2px 6px;
				border-radius: 4px;
			}
		}

		.person-extra {
			display: flex;
			align-items: center;
			gap: 8px;
			margin-top: 4px;
			font-size: 12px;
			color: var(--el-text-color-secondary);

			.person-dept,
			.person-position {
				padding: 1px 4px;
				background: var(--el-fill-color-lighter);
				border-radius: 2px;
			}
		}
	}
}

// 行内布局样式（参考部门组件）
.width100 {
	width: 100%;
}

.mb20 {
	margin-bottom: 20px;
}
</style>
